package controllers

import (
	"admin-glm-go/internal/models"
	"admin-glm-go/internal/response"
	"admin-glm-go/internal/utils"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// RoleListRequest 角色列表请求参数
type RoleListRequest struct {
	Page     int    `form:"page"`
	PageSize int    `form:"pageSize"`
	Name     string `form:"name"`
	Status   int    `form:"status"`
}

// AddRoleRequest 添加角色请求参数
type AddRoleRequest struct {
	Name         string   `json:"name" binding:"required"`
	Code         string   `json:"code" binding:"required"`
	Description  string   `json:"description"`
	Status       int      `json:"status"`
	PermissionIds []uint64 `json:"permissionIds"`
}

// UpdateRoleRequest 更新角色请求参数
type UpdateRoleRequest struct {
	ID           uint64   `json:"id" binding:"required"`
	Name         string   `json:"name" binding:"required"`
	Code         string   `json:"code" binding:"required"`
	Description  string   `json:"description"`
	Status       int      `json:"status"`
	PermissionIds []uint64 `json:"permissionIds"`
}

// RoleController 角色控制器
type RoleController struct {
	db *gorm.DB
}

// NewRoleController 创建角色控制器
func NewRoleController(db *gorm.DB) *RoleController {
	return &RoleController{db: db}
}

// GetRoleList 获取角色列表
// @Summary 获取角色列表
// @Description 获取角色列表
// @Tags 角色管理模块
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param page query int false "页码"
// @Param pageSize query int false "每页数量"
// @Param name query string false "角色名称"
// @Param status query int false "状态"
// @Success 200 {object} response.Response
// @Router /role/list [get]
func (ctrl *RoleController) GetRoleList(c *gin.Context) {
	var req RoleListRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		response.ParamError(c)
		return
	}

	// 设置默认值
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize <= 0 {
		req.PageSize = 10
	}

	// 构建查询条件
	query := ctrl.db.Model(&models.Role{})
	if req.Name != "" {
		query = query.Where("name LIKE ?", "%"+req.Name+"%")
	}
	if req.Status != 0 {
		query = query.Where("status = ?", req.Status)
	}

	// 获取总数
	var total int64
	query.Count(&total)

	// 分页查询
	var roles []models.Role
	offset := (req.Page - 1) * req.PageSize
	err := query.Preload("Permissions").Offset(offset).Limit(req.PageSize).Order("id DESC").Find(&roles).Error
	if err != nil {
		response.ServerError(c)
		return
	}

	// 构建响应数据
	var records []gin.H
	for _, role := range roles {
		var permissionIds []uint64
		for _, permission := range role.Permissions {
			permissionIds = append(permissionIds, permission.ID)
		}

		record := gin.H{
			"id":           role.ID,
			"name":         role.Name,
			"code":         role.Code,
			"description":  role.Description,
			"status":       role.Status,
			"permissions":  permissionIds,
			"createTime":   role.CreateTime.Format("2006-01-02 15:04:05"),
			"updateTime":   role.UpdateTime.Format("2006-01-02 15:04:05"),
		}
		records = append(records, record)
	}

	response.PageSuccess(c, total, records, req.Page, req.PageSize)
}

// AddRole 添加角色
// @Summary 添加角色
// @Description 添加角色
// @Tags 角色管理模块
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param body body AddRoleRequest true "角色信息"
// @Success 200 {object} response.Response
// @Router /role/add [post]
func (ctrl *RoleController) AddRole(c *gin.Context) {
	var req AddRoleRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.ParamError(c)
		return
	}

	// 检查角色名称是否已存在
	var count int64
	if err := ctrl.db.Model(&models.Role{}).Where("name = ?", req.Name).Count(&count).Error; err != nil {
		response.ServerError(c)
		return
	}
	if count > 0 {
		response.Error(c, 400, "角色名称已存在")
		return
	}

	// 检查角色编码是否已存在
	if err := ctrl.db.Model(&models.Role{}).Where("code = ?", req.Code).Count(&count).Error; err != nil {
		response.ServerError(c)
		return
	}
	if count > 0 {
		response.Error(c, 400, "角色编码已存在")
		return
	}

	// 创建角色
	role := models.Role{
		Name:        req.Name,
		Code:        req.Code,
		Description: req.Description,
		Status:      req.Status,
	}

	// 开启事务
	tx := ctrl.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 保存角色
	if err := tx.Create(&role).Error; err != nil {
		tx.Rollback()
		response.ServerError(c)
		return
	}

	// 分配权限
	if len(req.PermissionIds) > 0 {
		var permissions []models.Permission
		if err := tx.Where("id IN ?", req.PermissionIds).Find(&permissions).Error; err != nil {
			tx.Rollback()
			response.ServerError(c)
			return
		}

		if err := tx.Model(&role).Association("Permissions").Replace(permissions); err != nil {
			tx.Rollback()
			response.ServerError(c)
			return
		}
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		response.ServerError(c)
		return
	}

	response.Success(c, nil)
}

// UpdateRole 更新角色
// @Summary 更新角色
// @Description 更新角色
// @Tags 角色管理模块
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param body body UpdateRoleRequest true "角色信息"
// @Success 200 {object} response.Response
// @Router /role/update [put]
func (ctrl *RoleController) UpdateRole(c *gin.Context) {
	var req UpdateRoleRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.ParamError(c)
		return
	}

	// 查询角色
	var role models.Role
	if err := ctrl.db.First(&role, req.ID).Error; err != nil {
		response.NotFound(c)
		return
	}

	// 检查角色名称是否已存在（排除自己）
	var count int64
	if err := ctrl.db.Model(&models.Role{}).Where("name = ? AND id != ?", req.Name, req.ID).Count(&count).Error; err != nil {
		response.ServerError(c)
		return
	}
	if count > 0 {
		response.Error(c, 400, "角色名称已存在")
		return
	}

	// 检查角色编码是否已存在（排除自己）
	if err := ctrl.db.Model(&models.Role{}).Where("code = ? AND id != ?", req.Code, req.ID).Count(&count).Error; err != nil {
		response.ServerError(c)
		return
	}
	if count > 0 {
		response.Error(c, 400, "角色编码已存在")
		return
	}

	// 更新角色信息
	role.Name = req.Name
	role.Code = req.Code
	role.Description = req.Description
	role.Status = req.Status

	// 开启事务
	tx := ctrl.db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 保存角色
	if err := tx.Save(&role).Error; err != nil {
		tx.Rollback()
		response.ServerError(c)
		return
	}

	// 更新权限
	if len(req.PermissionIds) > 0 {
		var permissions []models.Permission
		if err := tx.Where("id IN ?", req.PermissionIds).Find(&permissions).Error; err != nil {
			tx.Rollback()
			response.ServerError(c)
			return
		}

		if err := tx.Model(&role).Association("Permissions").Replace(permissions); err != nil {
			tx.Rollback()
			response.ServerError(c)
			return
		}
	} else {
		// 清空权限
		if err := tx.Model(&role).Association("Permissions").Clear(); err != nil {
			tx.Rollback()
			response.ServerError(c)
			return
		}
	}

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		response.ServerError(c)
		return
	}

	response.Success(c, nil)
}

// DeleteRole 删除角色
// @Summary 删除角色
// @Description 删除角色
// @Tags 角色管理模块
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param id path int true "角色ID"
// @Success 200 {object} response.Response
// @Router /role/delete/{id} [delete]
func (ctrl *RoleController) DeleteRole(c *gin.Context) {
	id := utils.StringToUint(c.Param("id"))
	if id == 0 {
		response.ParamError(c)
		return
	}

	// 查询角色
	var role models.Role
	if err := ctrl.db.First(&role, id).Error; err != nil {
		response.NotFound(c)
		return
	}

	// 删除角色
	if err := ctrl.db.Delete(&role).Error; err != nil {
		response.ServerError(c)
		return
	}

	response.Success(c, nil)
}

// GetAllRoles 获取所有角色
// @Summary 获取所有角色
// @Description 获取所有角色
// @Tags 角色管理模块
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Success 200 {object} response.Response
// @Router /role/all [get]
func (ctrl *RoleController) GetAllRoles(c *gin.Context) {
	var roles []models.Role
	if err := ctrl.db.Where("status = ?", 1).Order("id ASC").Find(&roles).Error; err != nil {
		response.ServerError(c)
		return
	}

	// 构建响应数据
	var records []gin.H
	for _, role := range roles {
		record := gin.H{
			"id":   role.ID,
			"name": role.Name,
			"code": role.Code,
		}
		records = append(records, record)
	}

	response.Success(c, records)
}